package cn.ecut.tbjie.service;

import cn.ecut.tbjie.dao.PeopleDao;
import cn.ecut.tbjie.model.People;
import cn.ecut.tbjie.model.Tokens;
import cn.ecut.tbjie.utils.Hex2BinaryUtil;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.List;

@Service
public class PeopleService {

    /**
     * 此处自动装配已成功，在cn.ecut.tbjie.TbjieApplication中加了mapper的包扫描，但是dao对象有可能会被idea标红。
     */
    @Autowired
    private PeopleDao dao;

    @Autowired
    private LoginService service;


    /**
     * 添加用户
     *
     * @param people 用户实体类对象，用于封装用户信息
     * @return
     */
    public boolean addPeople(People people) {
        if (people.getPeopleName() == null || people.getPeopleName().equals("")) {
            return false;
        }
        if (people.getPeoplePsw() == null || people.getPeoplePsw().equals("")) {
            return false;
        }
        if (people.getPeopleNum() == null || people.getPeopleNum().equals("")) {
            return false;
        }
        dao.insertSelective(people);
        return true;
    }

    /**
     * 查询所有用户信息
     *
     * @return 所有保存用户信息的实体类组成的List集合
     */
    public List<People> findAll() {
        List<People> list = dao.selectAll();
        if (list.size() != 0) {
            return list;
        } else {
            return null;
        }
    }

//    /**
//     * 判断用户名是否冲突
//     * @param peopleName 用户名
//     * @return 如果用户名没有冲突，则返回true，否则返回false
//     */
//    public boolean inspectPeopleName(String peopleName){
//        try {
//            dao.findIdByPeopleName(peopleName);
//        } catch (Exception e) {
//            return true;
//        }
//        return false;
//    }

    /**
     * 将盐、随机插入位数组和新的用户名一并存到数据表中
     *
     * @param peopleName 用户名
     * @param salt       盐值
     * @param coreNum    核心码（随机插入位数组）
     * @return 是否添加成功
     */
    public boolean writeSaltAndRandomKeyByNewPeopleName(String peopleName, String salt, String coreNum) {
        People p = new People();
        p.setPeopleName(peopleName);
        p.setPeopleCoreNum(coreNum);
        JSONObject info = new JSONObject();
        info.put("salt", salt);
        p.setPeopleInfo(info.toString());
        int i = dao.insertSelective(p);
        return i != 0;
    }

    /**
     * 通过用户id将密码密文更新到people表中
     *
     * @param peopleId    用户id
     * @param passwordMD5 密码密文
     */
    public void updatePeoplePswById(Integer peopleId, String passwordMD5) {
        String peoplePSW = Hex2BinaryUtil.hexString2binaryString(passwordMD5);
        dao.putPeoplePswById(peopleId, peoplePSW);
    }


    /**
     * 通过用户姓名获取用户对象
     *
     * @param peopleName 用户姓名
     * @return 用户对象
     */
    public People getByName(String peopleName) {
        return dao.selectAllByName(peopleName);
    }

    /**
     * 通过用户名将token封装到people对象中并返回people对象
     *
     * @param peopleName 用户姓名
     * @return 包含了token的people对象
     */
    public People getTokenByName(String peopleName) {
        Tokens token = dao.selectTokenByName(peopleName);
        People people = dao.selectAllByName(peopleName);
        people.setToken(token);
        return people;
    }

    /**
     * 通过用户id获取其盐值
     *
     * @param peopleId 用户id
     * @return 用户盐值
     */
    public String getSaltById(Integer peopleId) {
        String s = dao.selectInfoById(peopleId);
        JSONObject info = new JSONObject(s);
        return info.getString("salt");
    }

    /**
     * 通过People对象获取新的盐值，对比上面的方法，省去一步访问数据库
     *
     * @param people People对象
     * @return 生成的新的盐值
     */
    public String getSaltByPeople(People people) {
        JSONObject info = new JSONObject(people.getPeopleInfo());
        return info.getString("salt");
    }

    /**
     * 生成新的盐值和随机插入位数组，并将新的盐值和随机插入位数组封装到初始对象中
     * 注意：不更新到数据表中！，并返回更新后的 People 对象
     *
     * @param people 待更新的 People 对象
     * @return 更新过后的 People 对象
     */
    public People updatePeopleSaltAndRandom(People people) {
        String salt = service.getSalt();
        try {
            people = updatePeopleInfoInPeople(people, "salt", salt);
            people.setPeopleCoreNum(service.getRandom(people.getPeopleCoreNum().split(",").length));
            return people;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return people;
    }

    /**
     * 根据所提供的people对象更新盐和核心码
     * @param people
     */
    public void updateSaltAndRandom(People people) {
        dao.updateSaltAndRandom(people);
    }


    /**
     * 更新 people 中的 Info 字段，将其中的 key 中 的 oldValue 替换为 value;
     * 注意：1：该方法没有将 数据表中的字段更新，仅仅只是更新了people对象中的 Info 字段的值
     * 2：如果在该对象的 Info 字段中 ， 没有找到 与参数 key 相对应的 key——value 值，则会抛出异常信息。
     *
     * @param people 待更新 Info 字段的 People对象
     * @param key    需要更新 的 key 值
     * @param value  需要更新 的 value 值
     * @return 返回 更新完成的 People对象
     * @throws Exception 没有找 出异常
     */
    public People updatePeopleInfoInPeople(People people, String key, String value) throws Exception {
        boolean flag = false;
        String peopleInfo = people.getPeopleInfo();
        JSONObject jsonObject = new JSONObject(peopleInfo);
        Iterator<String> keys = jsonObject.keys();
        JSONObject info = new JSONObject();
        while (keys.hasNext()) {
            String k = keys.next();
            String v = jsonObject.getString(k);
            if (k.equals(key)) {
                info.put(key, value);
                flag = true;
            } else {
                info.put(k, v);
            }
        }
        if (flag) {
            people.setPeopleInfo(info.toString());
            return people;
        } else {
            throw new Exception("没有找到这个key--value");
        }
    }
}
